package com.yt.setclaim.server.api.cms;

import com.yt.common.constant.Result;
import com.yt.setclaim.models.entity.*;
import com.yt.setclaim.models.service.*;
import com.yt.setclaim.models.dto.*;
import com.yt.setclaim.models.vo.ClaimProcessStatusVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Date;

@RestController
@RequestMapping("/cms/setclaim-process")
public class ClaimProcessController {

    @Autowired
    private MedicalReviewService medicalReviewService;

    @Autowired
    private ClaimCalcService claimCalcService;

    @Autowired
    private FinancialPayService financialPayService;

    @Autowired
    private ClaimCloseService claimCloseService;

    @Autowired
    private ClaimArchiveService claimArchiveService;

    /**
     * 第一步：医疗审核
     * 保存医疗审核信息并审核通过
     */
    @PostMapping("/medical-review")
    public Result<String> medicalReview(@RequestBody MedicalReviewDTO medicalReviewDTO) {
        // 检查是否已存在该索赔的审核记录
        MedicalReview existingReview = medicalReviewService.getByClaimId(Integer.valueOf(medicalReviewDTO.getClaimId()));
        if (existingReview != null) {
            return Result.fail("该索赔已存在医疗审核记录");
        }

        MedicalReview medicalReview = new MedicalReview();
        medicalReview.setClaimId(Integer.valueOf(medicalReviewDTO.getClaimId()));
        medicalReview.setAdminId(Integer.valueOf(medicalReviewDTO.getAdminId()));
        medicalReview.setSelfPay(medicalReviewDTO.getSelfPay() != null ? medicalReviewDTO.getSelfPay() : BigDecimal.ZERO);
        medicalReview.setThirdPartyPay(medicalReviewDTO.getThirdPartyPay() != null ? medicalReviewDTO.getThirdPartyPay() : BigDecimal.ZERO);
        medicalReview.setOtherDeduct(medicalReviewDTO.getOtherDeduct() != null ? medicalReviewDTO.getOtherDeduct() : BigDecimal.ZERO);
        medicalReview.setReviewResult(medicalReviewDTO.getReviewResult());
        medicalReview.setRejectReason(medicalReviewDTO.getRejectReason());
        medicalReview.setReviewTime(new Date());

        medicalReviewService.save(medicalReview);
        return Result.success("医疗审核完成");
    }

    /**
     * 第二步：理赔核算
     * 基于医疗审核结果进行赔付金额核算
     */
    @PostMapping("/claim-calc")
    public Result<String> claimCalc(@RequestBody ClaimCalcDTO claimCalcDTO) {
        // 检查是否已完成医疗审核
        MedicalReview medicalReview = medicalReviewService.getById(Integer.valueOf(claimCalcDTO.getReviewId()));
        if (medicalReview == null) {
            return Result.fail("未找到对应的医疗审核记录");
        }

        // 检查是否已存在该审核的核算记录
        ClaimCalc existingCalc = claimCalcService.getByReviewId(Integer.valueOf(claimCalcDTO.getReviewId()));
        if (existingCalc != null) {
            return Result.fail("该医疗审核已存在理赔核算记录");
        }

        // 计算总核减金额
        BigDecimal totalDeduct = medicalReview.getSelfPay()
                .add(medicalReview.getThirdPartyPay())
                .add(medicalReview.getOtherDeduct());

        ClaimCalc claimCalc = new ClaimCalc();
        claimCalc.setReviewId(Integer.valueOf(claimCalcDTO.getReviewId()));
        claimCalc.setAdminId(Integer.valueOf(claimCalcDTO.getAdminId()));
        claimCalc.setBaseAmount(claimCalcDTO.getBaseAmount());
        claimCalc.setTotalDeduct(totalDeduct);
        claimCalc.setPayRatio(claimCalcDTO.getPayRatio());
        
        // 计算赔付金额: (base_amount - total_deduct) * pay_ratio
        BigDecimal payAmount = claimCalc.getBaseAmount()
                .subtract(claimCalc.getTotalDeduct())
                .multiply(claimCalc.getPayRatio());
        claimCalc.setPayAmount(payAmount);

        claimCalc.setCalcTime(new Date());

        claimCalcService.save(claimCalc);
        return Result.success("理赔核算完成");
    }

    /**
     * 第三步：财务支付
     * 支付核算的金额
     */
    @PostMapping("/financial-pay")
    public Result<String> financialPay(@RequestBody FinancialPayDTO financialPayDTO) {
        // 检查是否已完成理赔核算
        ClaimCalc claimCalc = claimCalcService.getById(Integer.valueOf(financialPayDTO.getCalcId()));
        if (claimCalc == null) {
            return Result.fail("未找到对应的理赔核算记录");
        }

        // 检查是否已存在该核算的支付记录
        FinancialPay existingPay = financialPayService.getByCalcId(Integer.valueOf(financialPayDTO.getCalcId()));
        if (existingPay != null) {
            return Result.fail("该理赔核算已存在财务支付记录");
        }

        FinancialPay financialPay = new FinancialPay();
        financialPay.setCalcId(Integer.valueOf(financialPayDTO.getCalcId()));
        financialPay.setAdminId(Integer.valueOf(financialPayDTO.getAdminId()));
        financialPay.setPayAmount(claimCalc.getPayAmount()); // 默认使用核算金额
        financialPay.setAdjustAmount(financialPayDTO.getAdjustAmount() != null ? financialPayDTO.getAdjustAmount() : BigDecimal.ZERO);
        financialPay.setAdjustReason(financialPayDTO.getAdjustReason());
        financialPay.setPayTime(financialPayDTO.getPayTime());
        financialPay.setVoucherNo(financialPayDTO.getVoucherNo());
        financialPay.setPayStatus(financialPayDTO.getPayStatus() != null ? financialPayDTO.getPayStatus() : "已支付");
        financialPay.setCreateTime(new Date());

        financialPayService.save(financialPay);
        return Result.success("财务支付完成");
    }

    /**
     * 第四步：理赔结案
     * 填写结案时间和描述
     */
    @PostMapping("/claim-close")
    public Result<String> claimClose(@RequestBody ClaimCloseDTO claimCloseDTO) {
        // 检查是否已完成财务支付
        FinancialPay financialPay = financialPayService.getById(Integer.valueOf(claimCloseDTO.getPayId()));
        if (financialPay == null) {
            return Result.fail("未找到对应的财务支付记录");
        }

        // 检查是否已存在该支付的结案记录
        ClaimClose existingClose = claimCloseService.getByPayId(Integer.valueOf(claimCloseDTO.getPayId()));
        if (existingClose != null) {
            return Result.fail("该财务支付已存在理赔结案记录");
        }

        ClaimClose claimClose = new ClaimClose();
        claimClose.setPayId(Integer.valueOf(claimCloseDTO.getPayId()));
        claimClose.setAdminId(Integer.valueOf(claimCloseDTO.getAdminId()));
        claimClose.setCloseTime(claimCloseDTO.getCloseTime());
        claimClose.setCloseRemark(claimCloseDTO.getCloseRemark());
        claimClose.setCreateTime(new Date());

        claimCloseService.save(claimClose);
        return Result.success("理赔结案完成");
    }

    /**
     * 第五步：理赔归档
     * 选择盒号袋号进行归档
     */
    @PostMapping("/claim-archive")
    public Result<String> claimArchive(@RequestBody ClaimArchiveDTO claimArchiveDTO) {
        // 检查是否已完成理赔结案
        ClaimClose claimClose = claimCloseService.getById(Integer.valueOf(claimArchiveDTO.getCloseId()));
        if (claimClose == null) {
            return Result.fail("未找到对应的理赔结案记录");
        }

        // 检查是否已存在该结案的归档记录
        ClaimArchive existingArchive = claimArchiveService.getByCloseId(Integer.valueOf(claimArchiveDTO.getCloseId()));
        if (existingArchive != null) {
            return Result.fail("该理赔结案已存在归档记录");
        }

        ClaimArchive claimArchive = new ClaimArchive();
        claimArchive.setCloseId(Integer.valueOf(claimArchiveDTO.getCloseId()));
        claimArchive.setAdminId(Integer.valueOf(claimArchiveDTO.getAdminId()));
        claimArchive.setBoxNo(claimArchiveDTO.getBoxNo());
        claimArchive.setBagNo(claimArchiveDTO.getBagNo());
        claimArchive.setArchiveTime(claimArchiveDTO.getArchiveTime() != null ? claimArchiveDTO.getArchiveTime() : new Date());

        claimArchiveService.save(claimArchive);
        return Result.success("理赔归档完成");
    }

    /**
     * 查询理赔流程状态
     */
    @GetMapping("/status/{claimId}")
    public Result<ClaimProcessStatusVO> getClaimProcessStatus(@PathVariable("claimId") String claimId) {
        ClaimProcessStatusVO statusVO = new ClaimProcessStatusVO();
        statusVO.setClaimId(claimId);

        // 查询医疗审核状态
        MedicalReview medicalReview = medicalReviewService.getByClaimId(Integer.valueOf(claimId));
        if (medicalReview != null) {
            statusVO.setMedicalReviewStatus("已完成");
            statusVO.setReviewId(String.valueOf(medicalReview.getReviewId()));
            
            // 查询理赔核算状态
            ClaimCalc claimCalc = claimCalcService.getByReviewId(medicalReview.getReviewId());
            if (claimCalc != null) {
                statusVO.setClaimCalcStatus("已完成");
                statusVO.setCalcId(String.valueOf(claimCalc.getCalcId()));
                
                // 查询财务支付状态
                FinancialPay financialPay = financialPayService.getByCalcId(claimCalc.getCalcId());
                if (financialPay != null) {
                    statusVO.setFinancialPayStatus("已完成");
                    statusVO.setPayId(String.valueOf(financialPay.getPayId()));
                    
                    // 查询理赔结案状态
                    ClaimClose claimClose = claimCloseService.getByPayId(financialPay.getPayId());
                    if (claimClose != null) {
                        statusVO.setClaimCloseStatus("已完成");
                        statusVO.setCloseId(String.valueOf(claimClose.getCloseId()));
                        
                        // 查询理赔归档状态
                        ClaimArchive claimArchive = claimArchiveService.getByCloseId(claimClose.getCloseId());
                        if (claimArchive != null) {
                            statusVO.setClaimArchiveStatus("已完成");
                            statusVO.setArchiveId(String.valueOf(claimArchive.getArchiveId()));
                        } else {
                            statusVO.setClaimArchiveStatus("未完成");
                        }
                    } else {
                        statusVO.setClaimCloseStatus("未完成");
                        statusVO.setClaimArchiveStatus("未完成");
                    }
                } else {
                    statusVO.setFinancialPayStatus("未完成");
                    statusVO.setClaimCloseStatus("未完成");
                    statusVO.setClaimArchiveStatus("未完成");
                }
            } else {
                statusVO.setClaimCalcStatus("未完成");
                statusVO.setFinancialPayStatus("未完成");
                statusVO.setClaimCloseStatus("未完成");
                statusVO.setClaimArchiveStatus("未完成");
            }
        } else {
            statusVO.setMedicalReviewStatus("未完成");
            statusVO.setClaimCalcStatus("未完成");
            statusVO.setFinancialPayStatus("未完成");
            statusVO.setClaimCloseStatus("未完成");
            statusVO.setClaimArchiveStatus("未完成");
        }

        return Result.success(statusVO);
    }
}